#include "dbtools.h"
#include "dtwrecoge.h"

DBTools::DBTools(QObject *parent)
    : QObject{parent}
{

}

/*
 *
*/
QString DBTools::fitDataBaseName(QDateTime givenDateTime)
{
    QString dbNameString = "BCMS_Data";
    dbNameString += givenDateTime.date().toString(Qt::ISODate).mid(0,4) +
            givenDateTime.date().toString(Qt::ISODate).mid(5,7).mid(0,2);
    return dbNameString;
}

/*
 * 这个函数根据条件获取时间序列数据 QMap<QDateTime, double>
*/
QMap<QDateTime, double> DBTools::getUnderlineTagTimeSeris(QSqlDatabase dbConnection, QDateTime startTime,
                                                          QDateTime endTime, QString tagName, QString tableName, QString topCondition,
                                                          QString additionalCondition)
{
    // 先判断startTime和endTime是不是同一个
    QMap<QDateTime, double> resultMap;

    if(startTime.date().month() == endTime.date().month()) {
        QString dbName = fitDataBaseName(startTime);

        QString startTimeString = startTime.toString(Qt::ISODateWithMs).mid(0,10) + " " + startTime.toString(Qt::ISODateWithMs).mid(11);
        QString endTimeString = endTime.toString(Qt::ISODateWithMs).mid(0,10) + " " + endTime.toString(Qt::ISODateWithMs).mid(11);

        QString queryString = "select " + topCondition + "[CollectTime], [" + tagName + "] from [" + dbName + "].[dbo].[" + tableName +
                "] where CollectTime between '" + startTimeString + "' and '" + endTimeString + "'" + additionalCondition;
        qDebug() << queryString;
        QSqlQuery query(dbConnection);
        query.exec(queryString);
        while(query.next()) {
            resultMap.insert(query.value(0).toDateTime(), query.value(1).toDouble());
        }
        return resultMap;

    } else {

        QDateTime lastMonthSecond(startTime.date(), QTime(23,59,59,999));
        QDateTime nextMonthSecond(endTime.date(), QTime(00,00,00));

        QMap<QDateTime, double> frontMap = getUnderlineTagTimeSeris(dbConnection, startTime, lastMonthSecond, tagName, tableName, topCondition, additionalCondition);
        QMap<QDateTime, double> backMap = getUnderlineTagTimeSeris(dbConnection, nextMonthSecond, endTime, tagName, tableName, topCondition, additionalCondition);

        QMap<QDateTime, double>::ConstIterator frontMapIter = frontMap.constBegin();
        QMap<QDateTime, double>::ConstIterator backMapIter = backMap.constBegin();

        while(frontMapIter != frontMap.constEnd()) {
            resultMap.insert(frontMapIter.key(), frontMapIter.value());
            ++frontMapIter;
        }
        while(backMapIter != backMap.constEnd()) {
            resultMap.insert(backMapIter.key(), backMapIter.value());
            ++backMapIter;
        }
        return resultMap;
    }
}

int DBTools::getMinSize(int a, int b)
{
   if (a < b) return a;
   else return b;
}

double DBTools::calculateDTW(QList<QList<double>> originMatrix)
{
    int minSize=10000;
    for(int index=0;index < originMatrix.size(); ++index) {
        minSize = getMinSize(minSize, originMatrix[index].size());
    }

    QList<double> compareFormerTimeSerisList;

    for(int index=0; index < minSize; ++index) {
        compareFormerTimeSerisList.insert(originMatrix[3][index], (originMatrix[0][index] +
                originMatrix[1][index] +originMatrix[2][index]) / 3);
    }
    return DTW(compareFormerTimeSerisList, originMatrix[3]);
}

double DBTools::DTW(QList<double> prevList, QList<double> thisList)
{
    /*
     * TODO: 1. 将原有Map缩减一半，而且我发现，不需要时间，只需要double应该
    */
    double *first = new double[prevList.size()];
    double *second = new double[thisList.size()];

    for(int i=0;i<prevList.size();++i) {
        first[i] = prevList[i];
    }
    for(int i=0;i<thisList.size();++i) {
        second[i] = thisList[i];
    }

    DTWRecoge *dtw = new DTWRecoge;
    return dtw->DTWDistanceFun(first, prevList.size(), second, thisList.size(), 100);
}


